#ifndef C_COMPILER_INITSYNTAXANALYZER_H
#define C_COMPILER_INITSYNTAXANALYZER_H

#include <vector>
#include <set>
#include <stdexcept>
#include <iostream>
#include <fstream>
#include <sstream>
#include <Global.h>
#include <algorithm>
#include "AST.h"
using namespace std;

void readToReader(const string& filePath);
string initLine(string line);
int stackPush(int stackTop, const Production& production, ASTNode*& root);
void initProductions();
void initMap();
void processSymbolsToVnSetAndVtSet();
void output();
string getMapKey(const string& terminal, const string& nonTerminal);

void readToReader(const string& filePath) {
    ifstream file(filePath); // 打开文件
    if (!file.is_open()) {
        cerr << "Error opening file: " << filePath << endl;
        return;
    }
    string line;
    while (getline(file, line)) { // 读取文件的每一行
        line = initLine(line); // 对行进行预处理，假设您已定义了 initLine 函数
        // cout<<"line : "<<line<<endl;
        istringstream iss(line);
        string tokenCode, tokenType, tokenValue;
        if (getline(iss, tokenCode, ',') && getline(iss, tokenType, ',') && getline(iss, tokenValue, ',')) {
            try {
                int value = stoi(tokenCode); // 将字符串转换为整数
                readerVector.push_back(make_pair(value, tokenValue)); // 添加到reader向量中
            } catch (const exception &e) {
                cerr << "Error converting string to integer: " << e.what() << endl;
            }
        }
    }
    file.close(); // 关闭文件
}

string initLine(string line) {
    if (line.empty()) {
        return line;
    }
    if (line == ",  <SE,29>") {
        line = "29,,,";
        return line;
    }
    size_t strStartIndex_0 = line.find("\t");
    if (strStartIndex_0 != string::npos) {
        line = line.substr(strStartIndex_0);
    }

    string original_value;



    size_t strStartIndex_1 = line.find("<");
    size_t strStartIndex_2 = line.find(",");
    size_t strStartIndex_3 = line.find(">");

        // 提取原始值（位于 <...> 之前）
    if (strStartIndex_2 != string::npos && strStartIndex_3 != string::npos) {
        original_value = line.substr(strStartIndex_2 + 1, strStartIndex_3 - strStartIndex_2 - 1); // 例如 "123"
    } else {
        original_value = line; // 如果没有制表符，假设整行是原始值
    }

    if (strStartIndex_1 != string::npos && strStartIndex_2 != string::npos) {
        string token = line.substr(strStartIndex_1 + 1, strStartIndex_2 - strStartIndex_1 - 1);
        if (token == "IDN") {
            line = "30,Ident,"+original_value+",";
        } else if (token == "INT") {
            line = "31,IntConst,"+original_value+",";
        } else if(token == "FLOAT"){
            line = "32,floatConst,"+original_value+",";
        }else if (strStartIndex_2 != string::npos && strStartIndex_3 != string::npos) {
            string key = line.substr(strStartIndex_2 + 1, strStartIndex_3 - strStartIndex_2 - 1);
            int keyNum = stoi(key);
            if (map_i2s.find(keyNum) != map_i2s.end()) {
                line = key + "," + map_i2s[keyNum]+", ,";
            }
        }
    }

    return line;
}

int stackPush(int stackTop, const Production& production, ASTNode*& root) {

    int len = production.right_string.size(); // 获取产生式右侧符号的数量
    
    ASTNode* parent = stackVector.back().second; // 获取栈顶节点

    if(root == NULL){
        root = parent;
    }
    
    stackVector.pop_back();



    if (production.right_string.empty() || production.right_string[0] == "$") {
        // 如果产生式右侧第一个元素是"$"，表示空产生式，不进行压栈
        stackTop--;
        return stackTop;
    } else {
        // 从右到左将产生式的右侧符号压入栈中
        for (int i = len - 1; i >= 0; i--) {
            ASTNode* node = new ASTNode(production.right_string[i]);
            // cout << "push " << "\"" << production.right_string[i] << "\"" << endl;
            if(production.right_string[i] == "Ident" || production.right_string[i] == "IntConst" || production.right_string[i] == "floatConst"){
                // cout << "readerVector[" << stackTop + i - 1 << "].first : " << readerVector[stackTop + i - 1].first << endl;
                node->value = readerVector[i].second;
                // cout << "value : " << node->value << endl;
            }

            
            stackVector.push_back(make_pair(production.right_string[i], node));
        
            parent->children.push_back(node); 
        }
        // 返回更新后的栈顶位置，这里假设栈顶位置变化为增加的符号数-1

        reverse(parent->children.begin(), parent->children.end());
        
        return stackTop + len - 1;
    }
}

void initMap() {
    // 符号到编号的映射
    map_s2i = {
            {"int", 1}, {"void", 2}, {"return", 3}, {"const", 4}, {"main", 5},
            {"float", 6}, {"if", 7}, {"else", 8},{"+", 9}, {"-", 10}, {"*", 11},
            {"/", 12}, {"%", 13}, {"=", 14},{">", 15}, {"<", 16},{"!",17},
            {"==", 18}, {"<=", 19}, {">=", 20}, {"!=", 21},
            {"&&", 22}, {"||", 23}, {"(", 24}, {")", 25}, {"{", 26}, {"}", 27},
            {";", 28}, {",", 29}, {"Ident", 30}, {"IntConst", 31},{"floatConst",32} ,
            {"#", 33}

    };
    // 编号到符号的映射
    map_i2s = {
            {1, "int"}, {2, "void"}, {3, "return"}, {4, "const"}, {5, "main"},{6, "float"},
            {7, "if"}, {8, "else"},{9, "+"}, {10, "-"}, {11, "*"}, {12, "/"}, {13, "%"},
            {14, "="},{15, ">"}, {16, "<"},{17, "!"}, {18, "=="}, {19, "<="}, {20, ">="},
            {21, "!="},{22, "&&"}, {23, "||"}, {24, "("}, {25, ")"}, {26, "{"}, {27, "}"},
            {28, ";"}, {29, ","}, {30, "Ident"}, {31, "IntConst"}, {32,"floatConst"},{33,"#"}

    };
}

//修改后的文法读取操作函数，从grammar.txt中读取文法，解析的规则如下 left -> []right（注意替换grammar.txt的路径）
void initProductions() {
    ifstream file("/home/seary/compiler/C--Compiler/syntax_analysis/Grammar/NewGrammar"); // 打开grammar.txt文件
    if (!file.is_open()) {
        cerr << "Error opening grammar file" << endl;
        return;
    }

    string line;
    int index = 0; // 产生式索引
    while (getline(file, line)) {
        if (line.empty()) {
            continue; // 跳过空行
        }

        size_t arrowPos = line.find("->");
        if (arrowPos == string::npos) {
            cerr << "Invalid production_map rule: " << line << endl;
            continue;
        }

        string left = line.substr(0, arrowPos - 1); // 获取产生式左部
        string right = line.substr(arrowPos + 2); // 获取产生式右部

        istringstream iss(right);
        vector<string> rightSymbols;
        string symbol;
        while (iss >> symbol) {
            rightSymbols.push_back(symbol);
        }
        productionsArray[index++] = new Production(left, rightSymbols, line); // 创建产生式对象并添加到数组中
    }
    file.close(); // 关闭文件
    processSymbolsToVnSetAndVtSet();
}

//提取分析终结符和非终结符
void processSymbolsToVnSetAndVtSet() {
    vector<string> grammarStr;
    //size_t length = sizeof(productionsArray) / sizeof(productionsArray[0]);
    for(int i=0;i<GRAMMARSIZE;i++){
        grammarStr.push_back(productionsArray[i]->production_string);
    }
    // 将产生式存储到production
    for (const string& str : grammarStr) {
        // 将产生式按照 -> 分开
        string left = str.substr(0, str.find("->"));
        string right = str.substr(str.find("->") + 2);
        left = left.substr(left.find_first_not_of(" "), left.find_last_not_of(" ") + 1);
        right = right.substr(right.find_first_not_of(" "), right.find_last_not_of(" ") + 1);
        // 如果产生式里已经有left，先取出原来的值
        vector<string> list = production_map[left];
        list.push_back(right);
        production_map[left] = list;
        VnSet.insert(left); // 在产生式左边的一定是非终结符
    }
    // 寻找终结符
    for (const string& ch : VnSet) {
        for (const string& str : production_map[ch]) {
            istringstream iss(str);
            string token;
            while (iss >> token) {
                if (!VnSet.count(token)) {
                    VtSet.insert(token);
                }
            }
        }
    }

    //仅测试用，可删
//    cout << "**************终结符*****************" << endl;
//    for (const string& ch : VtSet) {
//        cout << ch << endl;
//    }
//
//    cout << "**************非终结符*****************" << endl;
//    for (const string& ch : VnSet) {
//        cout << ch << endl;
//    }
}

//仅测试用，可删
void output() {
//    cout << "*************FIRST集************" << endl;
//    for (const string &c: VnSet) {
//        const unordered_set <string> &set = FirstSet[c];
//        cout << c << " : ";
//        for (const string &var: set) {
//            cout << var << " ";
//        }
//        cout << endl;
//    }
//    cout << endl;
//
//    cout << "**************FOLLOW集*************" << endl;
//    for (const string &c: VnSet) {
//        const unordered_set <string> &set = FollowSet[c];
//        cout << c << " : ";
//        for (const string &var: set) {
//            cout << var << " ";
//        }
//        cout << endl;
//    }
//    cout << endl;
}

#endif //C_COMPILER_INITSYNTAXANALYZER_H
